#ifndef _ITMC328_H_
#define	_ITMC328_H_

#include "types.h"
#include "stm8l15x.h"

typedef enum{
	ITMC328_DISCONNECTED,
	ITMC328_OK,
	ITMC328_BUSY,
	ITMC328_GENERIC_ERROR
}ITMC328_ERROR_TYPE;


typedef struct{
	ErrorStatus (*pfCopyByte)(uint8_t);
	uint32_t remainingDataSize;
}ITMC328_COPY_JPEG_FUNCTION;


ITMC328_ERROR_TYPE Itmc328_Init(void);
void Itmc328_DeInit(void);
ITMC328_ERROR_TYPE Itmc328_TakeAPicture(ErrorStatus (*pfCopyByteCbk)(uint8_t));
ITMC328_ERROR_TYPE Itmc328_GetImageData(uint16_t *lenByte);


#ifdef	_ITMC328_C_
#include "stm8l15x_usart.h"

//-TYPES
#define	MAX_CONNECTION_RETRY	60
#define	LAST_DATA_PACKET_ID		0xF0F0
#define	PACKET_DATA_SIZE		128

#define	POWER_PIN			GPIO_Pin_7
#define	POWER_PORT			GPIOD

typedef enum{
	S_UNINITED,
	S_OK,
	S_WORKING,
	S_DISCONNECTED,
	S_ERROR
}ITMC328_STATE;

typedef enum{
	CMD_GET_DATA			= 0x0000,	///< codice fittizio usato solo per il trasferimento dell'immagine

	CMD_INITIAL				= 0xAA01,
	CMD_GET_PICTURE			= 0xAA04,
	CMD_SNAPSHOT			= 0xAA05,
	CMD_SET_PACKAGE_SIZE	= 0xAA06,
	CMD_SET_BAUDRATE		= 0xAA07,
	CMD_RESET				= 0xAA08,
	CMD_POWER_OFF			= 0xAA09,
	CMD_DATA				= 0xAA0A,
	CMD_SYNC				= 0xAA0D,
	CMD_ACK					= 0xAA0E,
	CMD_NACK				= 0xAA0F
}ITMC328_CMD_ID;

typedef enum{
	RES_80x64	= 0x01,
	RES_160x128	= 0x03,
	RES_320x240	= 0x05,
	RES_640x480	= 0x07
}ITMC328_JPEG_RES;

typedef enum{
	SNAPSHOT	= 0x01,
	PREVIEW		= 0x05
}ITMC328_PIC_TYPE;

typedef enum{
	BAUD_7200	= 0x01FF,
	BAUD_14400	= 0x017F,
	BAUD_28800	= 0x013F,
	BAUD_57600	= 0x011F,
	BAUD_115200	= 0x010F
}ITMC328_BAUD_RATE;

typedef enum{
	TOTAL_RESET			= 0x00,
	STATE_MACHINE_RESET = 0x01
}ITMC328_RESET_TYPE;

typedef enum{
	ERR_PICTURE_TYPE				= 0x01,
	ERR_PICTURE_UP_SCALE			= 0x02,
	ERR_PICTURE_SCALE				= 0x03,
	ERR_UNEXPECTED_REPLY			= 0x04,
	ERR_SEND_PICTURE_TIMEOUT		= 0x05,
	ERR_UNEXPECTED_COMMAND			= 0x06,
	ERR_SRAM_JPEG_TYPE				= 0x07,
	ERR_SRAM_JPEG_SIZE				= 0x08,
	ERR_PICTURE_FORMAT				= 0x09,
	ERR_PICTURE_SIZE				= 0x0A,
	ERR_PARAMETER					= 0x0B,
	ERR_SEND_REGISTER_TIMEOUT		= 0x0C,
	ERR_COMMAND_ID					= 0x0D,
	ERR_PICTURE_NOT_READY			= 0x0F,
	ERR_TRANSFER_PACKAGE_NUMBER		= 0x10,
	ERR_SET_TRANSFER_PACKAGE_SIZE	= 0x11,
	ERR_COMMAND_HEADER				= 0xF0,
	ERR_COMMAND_LENGTH				= 0xF1,
	ERR_SEND_PICTURE				= 0xF5,
	ERR_SEND_COMMAND				= 0xFF
}ITMC328_NAK_ERROR_TYPE;

// TODO: VERIFICARE
typedef union{
	uint8_t b[6];

	struct{
		ITMC328_CMD_ID cmd;
		uint8_t par1;
		uint8_t par2;
		uint8_t par3;
		uint8_t par4;
	};
}ITMC328_CMD_PACKET;

typedef struct{
	uint16_t	id;
	uint16_t dataSize;
	uint8_t *imageData;
	uint16_t verifyCode;
}ITMC328_DATA_PACKET;

typedef struct{
	ITMC328_STATE state;
	ITMC328_COPY_JPEG_FUNCTION transfer;
	ITMC328_CMD_PACKET txPkt;
	ITMC328_CMD_PACKET rxPkt;
}ITMC328_INSTANCE_TYPE;


//-PRIVATE PROTOTYPE
static ErrorStatus itmc328_cmd_initial(ITMC328_JPEG_RES resolution);
static ErrorStatus itmc328_cmd_getPicture(ITMC328_PIC_TYPE type);
static ErrorStatus itmc328_cmd_snapshot(void);
static ErrorStatus itmc328_cmd_setPackageSize(uint16_t pkgSize);
static ErrorStatus itmc328_cmd_setBaudrate(ITMC328_BAUD_RATE baudRate);
static ErrorStatus itmc328_cmd_reset(ITMC328_RESET_TYPE type);
static ErrorStatus itmc328_cmd_powerOff(void);
static ErrorStatus itmc328_get_data(ITMC328_PIC_TYPE *picType, uint32_t *len);
static ErrorStatus itmc328_get_dataPkt(uint16_t *pktSize);
static ErrorStatus itmc328_cmd_sync(void);
static void itmc328_cmd_ack(ITMC328_CMD_ID cmd, uint16_t pkgId);
static void itmc328_get_nack(const uint8_t *parBuffer, ITMC328_NAK_ERROR_TYPE *error);
static ErrorStatus itmc328_waitAck(ITMC328_CMD_ID rxAckCmd);
static ErrorStatus itmc328_waitCmd(ITMC328_CMD_ID cmd);
static uint16_t itmc328_receive(uint8_t *rxBuffer, uint16_t maxLen, bool wait);
static ErrorStatus itmc328_receiveCmd(ITMC328_CMD_ID *pRxCmd);
static ErrorStatus itmc328_getch(uint8_t *c);
static ErrorStatus itmc328_send(const uint8_t *rxBuffer, uint8_t len);
static ErrorStatus itmc328_putch(uint8_t c);


#endif	// _ITMC328_C_

#endif
